home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / Lightspeed-p-c / Symantec / Think Pascal / LightSpeed.p < prev    next >
Encoding:
Text File  |  1994-12-04  |  11.6 KB  |  464 lines  |  [TEXT/PJMM]

  1. program LightSpeed;
  2.     uses
  3.         Sound, Palettes, ToolUtils, Resources, Windows;
  4.     const
  5.         MBarHeight = $BAA;            {Address of menubar height}
  6.         HUDColor = blackColor;
  7.         IndexColor = greenColor;
  8.         starNumber = 40;            {Number of stars on the screen at one time}
  9.         photonSnd = 9000;
  10.         engineSnd = 9001;
  11.     type
  12.         IntPtr = ^integer;
  13.         StarRecord = record
  14.                 h, v: extended;
  15.                 distance: extended;
  16.             end;
  17.         StarList = array[1..starNumber] of StarRecord;
  18.     var
  19.         stars: StarList;
  20.         starsWindow: WindowPtr;
  21.         dataHandle: Handle;
  22.         currentPort: GrafPtr;
  23.         starswindowRect: Rect;
  24.         GrayRgn: RgnHandle;
  25.         MBarHeightPtr: IntPtr;
  26.         oldMBarHeight: Integer;
  27.         mBarRgn: RgnHandle;
  28.         colorList: array[0..2] of integer;
  29.         TheEvent: EventRecord;
  30.  
  31.     function Randomize (high: Integer): extended;        {Random number}
  32. {between -(high) and (high)}
  33.         var
  34.             rawResult: LONGINT;
  35.     begin
  36.         rawResult := Random;
  37.         Randomize := ((rawResult * high) / 32768)
  38.     end;
  39.  
  40.     function RandMinMax (low, high: extended): extended;        {Pos number}
  41. {between low and high}
  42.         var
  43.             rawResult: LONGINT;
  44.     begin
  45.         rawResult := Random;
  46.         RandMinMax := ABS(rawResult * (high - low) / 32768) + low
  47.     end;
  48.  
  49.     function IntRandomize (high: Integer): Integer;                {Random}
  50. {integer between 1 and high}
  51.         var
  52.             rawResult: LONGINT;
  53.     begin
  54.         rawResult := Random;
  55.         IntRandomize := ABS((rawResult * high) div 32768)
  56.     end;
  57.  
  58.     function Sgn (number: Integer): Integer;            {Signum function}
  59.     begin
  60.         Sgn := 0;
  61.         if number > 0 then
  62.             Sgn := 1;
  63.         if number < 0 then
  64.             Sgn := -1;
  65.     end;
  66.  
  67.     procedure HideMenuBar;
  68.         var
  69.             mBarRect: Rect;
  70.     begin
  71.         oldMBarHeight := MBarHeightPtr^;
  72.         MBarHeightPtr^ := 0;                                        { Make the}
  73. {Menu bar's height zero }
  74.         with qd.screenBits.bounds do
  75.             SetRect(mBarRect, left, top, right, top + oldMBarHeight);
  76.         mBarRgn := NewRgn;
  77.         RectRgn(mBarRgn, mBarRect);
  78.         UnionRgn(GrayRgn, mBarRgn, GrayRgn);  { Tell the desktop it}
  79. {covers the menu bar }
  80.         PaintOne(nil, mBarRgn);                    { redraw desktop }
  81.     end;
  82.  
  83.     procedure ShowMenuBar;
  84.     begin
  85.         MBarHeightPtr^ := oldMBarHeight;
  86.         DiffRgn(GrayRgn, mBarRgn, GrayRgn);        { remove the menu bar from}
  87. {the desktop }
  88.         DisposeRgn(mBarRgn)
  89.     end;
  90.  
  91.     procedure CenterOrigin;
  92.         var
  93.             centerX, centerY: Integer;
  94.     begin
  95.         with currentPort^.portRect do
  96.             begin
  97.                 centerX := -(ABS(right div 2));
  98.                 centerY := -(ABS(bottom div 2));
  99.                 SetOrigin(centerX, centerY)
  100.             end
  101.     end;
  102.  
  103.     procedure ClearScrn;
  104.         var
  105.             oldpenState, oldBkColor: Integer;
  106.             winMgrPort: GrafPtr;
  107.             menuRect: Rect;
  108.     begin
  109.         oldPenState := currentPort^.pnMode;
  110.         GetWMgrPort(winMgrPort);
  111.         oldBkColor := winMgrPort^.bkColor;
  112.         SetPort(winMgrPort);
  113.         BackColor(blackColor);
  114.         SetRect(menuRect, 0, 0, qd.screenBits.bounds.right, 20);
  115.         EraseRect(winMgrPort^.portRect);
  116.         BackColor(oldBkColor);
  117.         SetPort(currentPort)
  118.     end;
  119.  
  120.     procedure MainLoop;
  121.         const
  122.             PhotonNum = 18;
  123.             MaxDist = 24;
  124.         type
  125.             PhotonVector = record
  126.                     h: extended;
  127.                     v: extended;
  128.                     psize: extended;
  129.                 end;
  130.         var
  131.             starColor: RGBColor;
  132.             star, i, t: Integer;
  133.             hPos, vPos: Integer;
  134.             photon: array[1..PhotonNum] of PhotonVector;
  135.             oldPhoton: PhotonVector;
  136.             photonCount: Integer;
  137.             oldpsize: extended;
  138.             continue, past, offscreen: BOOLEAN;
  139.             shipSpeed, dist: extended;
  140.             starRect: Rect;
  141.             windowWidth, windowHight, midH, midV: Integer;
  142.             mouseLoc, oldmouseLoc: Point;
  143.             hOffset, vOffset: Integer;
  144.             hRect, vRect: Rect;
  145.             engineSound, photonSound: Handle;
  146.             soundChannel: SndChannelPtr;
  147.             stopCommand: SndCommand;
  148.             err: OSErr;
  149.         procedure MakeRect (h, v: extended; distance: extended; var theRect: Rect);
  150.             var
  151.                 size: Integer;
  152.         begin
  153.             with theRect do
  154.                 begin
  155.                     size := ROUND(MaxDist / (distance + 0.01));
  156.                     left := ROUND(h);
  157.                     top := ROUND(v);
  158.                     right := left + size;
  159.                     bottom := top + size;
  160.                     OffsetRect(theRect, -(size div 2), -(size div 2));
  161.                 end
  162.         end;
  163.         procedure LoadStars;
  164.             var
  165.                 star: Integer;
  166.                 starRect: Rect;
  167.         begin
  168.             for star := 1 to starNumber do
  169.                 begin
  170.                     stars[star].h := Randomize(midH);
  171.                     stars[star].v := Randomize(midV);
  172.                     stars[star].distance := RandMinMax(3, MaxDist);
  173.                     MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  174.                     InvertOval(starRect)
  175.                 end
  176.         end;
  177.         procedure DoMouseDown;
  178.         begin
  179.             if photonCount < 10 then
  180.                 begin
  181.                     err := SndDoImmediate(soundChannel, stopCommand);
  182.                     err := SndPlay(soundChannel, photonSound, TRUE);
  183.                     photon[photonCount + 1].h := -midH;
  184.                     photon[photonCount + 1].v := midV;
  185.                     photon[photonCount + 2].h := midH;
  186.                     photon[photonCount + 2].v := midV;
  187.                     photon[photonCount + 1].psize := 48;
  188.                     photon[photonCount + 2].psize := 48;
  189.                     photonCount := photonCount + 2;
  190.                 end
  191.         end;
  192.         procedure DoKeyDown;
  193.             var
  194.                 chCode: Integer;
  195.                 theChar: char;
  196.         begin
  197.             chCode := BitAnd(TheEvent.message, CharCodeMask);
  198.             theChar := CHR(chCode);
  199.             if theChar = '+' then
  200.                 shipSpeed := shipSpeed + 0.1;
  201.             if theChar = '-' then
  202.                 shipSpeed := shipSpeed - 0.1;
  203.             if (theChar = 'q') or (theChar = 'Q') then
  204.                 continue := FALSE;
  205.             if theChar = ' ' then
  206.                 DoMouseDown;
  207.             if theChar = '4' then
  208.                 hPos := hPos - 5;
  209.             if theChar = '7' then
  210.                 begin
  211.                     vPos := vPos + 5;
  212.                     hPos := hPos - 5;
  213.                 end;
  214.             if theChar = '8' then
  215.                 vPos := vPos + 5;
  216.             if theChar = '9' then
  217.                 begin
  218.                     vPos := vPos + 5;
  219.                     hPos := hPos + 5;
  220.                 end;
  221.             if theChar = '6' then
  222.                 hPos := hPos + 5;
  223.             if theChar = '3' then
  224.                 begin
  225.                     vPos := vPos - 5;
  226.                     hPos := hPos + 5;
  227.                 end;
  228.             if theChar = '2' then
  229.                 vPos := vPos - 5;
  230.             if theChar = '1' then
  231.                 begin
  232.                     vPos := vPos - 5;
  233.                     hPos := hPos - 5;
  234.                 end;
  235.             if theChar = '5' then
  236.                 begin
  237.                     vPos := 0;
  238.                     hPos := 0
  239.                 end;
  240.         end;
  241.         procedure DrawPhoton (h, v, psize: extended);
  242.             var
  243.                 t, offset, offset2: Integer;
  244.                 h2, v2: Integer;
  245.                 photonRect: Rect;
  246.         begin
  247.             h2 := ROUND(h);
  248.             v2 := ROUND(v);
  249.             for t := 0 to 4 do
  250.                 begin
  251.                     ForeColor(colorList[ABS(IntRandomize(3))]);
  252.                     offset := ROUND(SIN(psize + t) * psize);
  253.                     offset2 := ROUND(SIN((psize + t) * 2) * psize);
  254.                     MoveTo(h2 - offset, v2 - offset2);
  255.                     LineTo(h2 + offset, v2 + offset2)
  256.                 end;
  257.         end;
  258.     begin        (*Main Loop*)
  259.         CenterOrigin;
  260.         colorList[0] := blueColor;
  261.         colorList[1] := blueColor;
  262.         colorList[2] := cyanColor;
  263.         BackColor(blackColor);
  264.         with currentPort^.portRect do
  265.             begin
  266.                 windowWidth := (right - left);
  267.                 windowHight := (bottom - top)
  268.             end;
  269.         midH := windowWidth div 2;
  270.         midV := windowHight div 2;
  271.         LoadStars;
  272.         ForeColor(HUDColor);
  273.         PenNormal;
  274.         PenPat(qd.black);
  275.         engineSound := GetResource('snd ', engineSnd);
  276.         photonSound := GetResource('snd ', photonSnd);
  277.         with stopCommand do
  278.             begin
  279.                 cmd := quietCmd;
  280.                 param1 := 0;
  281.                 param2 := 0;
  282.             end;
  283.         soundChannel := nil;
  284.         err := SndNewChannel(soundChannel, sampledSynth, initMono, nil);
  285.         continue := TRUE;
  286.         photonCount := 0;
  287.         shipSpeed := 0;
  288.         hPos := 0;
  289.         vPos := 0;
  290.         with starColor do
  291.             begin
  292.                 red := $AAAA;
  293.                 green := $AAAA;
  294.                 blue := $BBBB;
  295.             end;
  296.         SetEventMask(mDownMask + keyDownMask + autoKeyMask);
  297.         GetMouse(oldmouseLoc);
  298.         while continue do
  299.             begin
  300.                 if GetNextEvent(EveryEvent, TheEvent) then
  301.                     case TheEvent.what of
  302.                         mouseDown: 
  303.                             DoMouseDown;
  304.                         keyDown: 
  305.                             DoKeyDown;
  306.                         autoKey: 
  307.                             DoKeyDown;
  308.                         otherwise
  309.                             ;
  310.                     end;
  311.                 GetMouse(mouseLoc);
  312.                 if not EqualPt(mouseLoc, oldmouseLoc) then
  313.                     begin
  314.                         hPos := hPos + (mouseLoc.h - oldmouseLoc.h);
  315.                         vPos := vPos + (mouseLoc.v - oldmouseLoc.v);
  316.                         oldmouseLoc := mouseLoc;
  317.                     end;
  318.                 ForeColor(IndexColor);
  319.                 PenMode(SrcCopy);
  320.                 if ABS(hPos) > (midH - 2) then
  321.                     hPos := Sgn(hPos) * (midH - 2);
  322.                 if ABS(vPos) > (midV - 2) then
  323.                     vPos := Sgn(vPos) * (midV - 2);
  324.                 vRect.left := -(midH);
  325.                 vRect.right := -(midH) + 8;
  326.                 vRect.top := vPos;
  327.                 vRect.bottom := vPos + 2;
  328.                 PaintRect(vRect);
  329.                 hRect.bottom := midV;
  330.                 hRect.top := midV - 8;
  331.                 hRect.left := hPos;
  332.                 hRect.right := hPos + 2;
  333.                 PaintRect(hRect);
  334.                 hOffset := -hPos;
  335.                 vOffset := vPos;
  336.                 PenMode(SrcCopy);
  337.                 if photonCount > 0 then
  338.                     begin
  339.                         PenMode(SrcCopy);
  340.                         for i := 1 to photonCount do
  341.                             DrawPhoton(photon[i].h, photon[i].v, photon[i].psize);
  342.                     end;
  343.                 for star := 1 to starNumber do            {Calculate new star}
  344. {position, if star out of window, reset it}
  345.                     begin
  346.                         MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  347.                         EraseOval(starRect);
  348.                         if (shipSpeed < 0) and (stars[star].distance >= MaxDist) then
  349.                             past := TRUE;
  350.                         if (shipSpeed > 0) and (stars[star].distance <= 0) then
  351.                             past := TRUE;
  352.                         if (ABS(stars[star].v) > midV) or (ABS(stars[star].h) > midH) then
  353.                             offscreen := TRUE;
  354.                         if (past or offscreen) then
  355.                             begin            {new star}
  356.                                 past := FALSE;
  357.                                 offscreen := FALSE;
  358.                                 if shipSpeed >= 0 then
  359.                                     begin
  360.                                         stars[star].v := Randomize(midV - 10);
  361.                                         stars[star].h := Randomize(midH - 10);
  362.                                         stars[star].distance := maxDist;
  363.                                     end
  364.                                 else            {shipSpeed < 0}
  365.                                     case IntRandomize(3) of
  366.                                         1: 
  367.                                             begin
  368.                                                 if IntRandomize(2) = 1 then
  369.                                                     stars[star].v := midV
  370.                                                 else
  371.                                                     stars[star].v := -midV;
  372.                                                 stars[star].h := Randomize(midH);
  373.                                                 stars[star].distance := RandMinMax(2, MaxDist - 1);
  374.                                             end;
  375.                                         2: 
  376.                                             begin
  377.                                                 stars[star].v := Randomize(midV);
  378.                                                 if IntRandomize(2) = 1 then
  379.                                                     stars[star].h := midH
  380.                                                 else
  381.                                                     stars[star].h := -midH;
  382.                                                 stars[star].distance := RandMinMax(2, MaxDist - 1);
  383.                                             end;
  384.                                     end
  385.                             end            {new star}
  386.                         else
  387.                             begin
  388.                                 dist := 6 * stars[star].distance;                {How much distance}
  389. {affects apparent speed}
  390.                                 stars[star].h := stars[star].h * (shipSpeed + dist) / dist + (hOffset div 8);
  391.                                 stars[star].v := stars[star].v * (shipSpeed + dist) / dist + (vOffset div 6);
  392.                                 stars[star].distance := stars[star].distance - (shipSpeed / 6);
  393.                             end;
  394.                         MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  395.                         RGBForeColor(starColor);
  396.                         PaintOval(starRect);
  397.                     end;
  398.                 PenPat(qd.gray);
  399.                 ForeColor(yellowColor);
  400.                 i := 0;
  401.                 while i < midH do
  402.                     begin
  403.                         i := i + 50;
  404.                         MoveTo(i, -5);
  405.                         Line(0, 10);
  406.                         MoveTo(-i, -5);
  407.                         Line(0, 10);
  408.                     end;
  409.                 i := 0;
  410.                 while i < midV do
  411.                     begin
  412.                         i := i + 50;
  413.                         MoveTo(-5, i);
  414.                         Line(10, 0);
  415.                         MoveTo(-5, -i);
  416.                         Line(10, 0);
  417.                     end;
  418.                 PenNormal;
  419.                 if photonCount > 0 then
  420.                     begin
  421.                         PenMode(SrcBic);
  422.                         for i := 1 to photonCount do
  423.                             begin
  424.                                 oldphoton := photon[i];
  425.                                 photon[i].h := photon[i].h * 0.86 + (hOffset div 8);
  426.                                 photon[i].v := photon[i].v * 0.86 + (vOffset div 6);
  427.                                 DrawPhoton(oldphoton.h, oldphoton.v, oldphoton.psize);
  428.                                 oldpsize := photon[i].psize;
  429.                                 photon[i].psize := photon[i].psize * 0.9;
  430.                                 if ABS(oldpsize - photon[i].psize) < 0.09 then
  431.                                     begin
  432.                                         for t := i to (photonCount - 1) do
  433.                                             photon[t] := photon[t + 1];
  434.                                         photonCount := photonCount - 1;
  435.                                     end;
  436.                             end;
  437.                     end;
  438.                 EraseRect(hRect);
  439.                 EraseRect(vRect);
  440.             end;
  441.         ReleaseResource(photonSound);
  442.         ReleaseResource(engineSound);
  443.         err := SndDisposeChannel(soundChannel, TRUE);
  444.         FlushEvents(everyEvent, 0);
  445.     end;
  446.  
  447. begin        (*Main Block*)
  448.     with qd.screenBits.bounds do
  449.         begin
  450.             MBarHeightPtr := IntPtr(MBarHeight);
  451.             GrayRgn := GetGrayRgn;
  452.             HideMenuBar;
  453.             starsWindow := NewCWindow(nil, qd.screenBits.bounds, 'LightSpeed', TRUE, NoGrowDocProc, WindowPtr(-1), FALSE, LONGINT(dataHandle));
  454.             SetPort(starsWindow);
  455.         end;
  456.     GetPort(currentPort);
  457.     ClearScrn;
  458.     HideCursor;
  459.     MainLoop;
  460.     ShowCursor;
  461.     ShowMenuBar;
  462.     FlushEvents(MDownMask, 0)            {Clear Event Queue of all mouseDown}
  463. {events}
  464. end.